package com.syf.core.config;

import cn.hutool.core.util.StrUtil;
import com.syf.core.cont.SyfCoreCont;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.*;

import java.util.HashMap;
import java.util.Map;

@Slf4j
public class SyApplicationConfiguration {
    private static String appBasePackage;

    private final ConfigurableApplicationContext springContext;

    /**
     * 最初application显式配置的参数，不包括之后将app component configuration的默认参数回写至environment的那部分
     */
    private final Map<String, Object> originParamMap;

    public SyApplicationConfiguration(ConfigurableApplicationContext springContext) {
        ConfigurableEnvironment environment = springContext.getEnvironment();
        this.springContext = springContext;

        // 此时environment仅是application显式配置的参数
        originParamMap = new HashMap<>(64);
        originParamMap.putAll(environment.getSystemEnvironment());
        for (PropertySource<?> propertySource : environment.getPropertySources()) {
            if (propertySource instanceof EnumerablePropertySource) {
                // warning: Raw use of parameterized class 'EnumerablePropertySource
                EnumerablePropertySource enumerablePS = (EnumerablePropertySource) propertySource;
                for (String propertyName : enumerablePS.getPropertyNames()) {
                    originParamMap.put(propertyName, enumerablePS.getProperty(propertyName));
                }
            }
        }

        if (log.isDebugEnabled()) {
            log.debug("将显式定义的配置参数加载至SyfApplicationConfiguration");
        }

    }

    /**
     * 回写Spring @Configuration对象的默认配置参数内容
     */
    void loadSpringConfigurationBeanArgs(PropertiesPropertySource propertiesPropertySource) {
        // 加载@ConfigurationProperties定义的配置参数的初始默认值
        if (springContext.getEnvironment().getPropertySources().contains(SyfCoreCont.DEFAULT_PROPERTY_SOURCE_NAME)) {
            CompositePropertySource compositePropertySource = (CompositePropertySource) springContext.getEnvironment().getPropertySources().get(SyfCoreCont.DEFAULT_PROPERTY_SOURCE_NAME);

            if (propertiesPropertySource != null) {
                compositePropertySource.addPropertySource(propertiesPropertySource);
            }
        }
    }

    /**
     * 判断environment中是否包含此配置参数
     */
    public boolean containsProperty(String key) {
        return springContext.getEnvironment().containsProperty(key);
    }

    /**
     * 获取应用所有定义的配置参数
     */
    public String getPropertyFromApplication(String propertyName) {
        return springContext.getEnvironment().getProperty(propertyName);
    }

    public Map<String, Object> getOriginPropertyMapByPrefix(String prefix) {
        Map<String, Object> propertyMap = new HashMap<>();

        for (Map.Entry<String, Object> entry : originParamMap.entrySet()) {
            if (entry.getKey().startsWith(prefix)) {
                propertyMap.put(entry.getKey(), entry.getValue());
            }
        }

        return propertyMap;
    }

    public static String getAppBasePackage() {
        return appBasePackage;
    }

    public static void setAppBasePackage(String appBasePackage) {
        SyApplicationConfiguration.appBasePackage = appBasePackage;
    }

}
